package com.gzhryc.shared_device.oem.code.statistics.services;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.time.DateFormatUtils;

import com.gzhryc.common.DateTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.shared_device.common.device.services.DeviceService;
import com.gzhryc.shared_device.oem.code.place.services.PlacePhysicalStoreService;
import com.gzhryc.shared_device.oem.code.place.services.dto.PlacePhysicalStoreSearch;
import com.gzhryc.shared_device.oem.code.statistics.dao.ProjectDayStatisticsDao;
import com.gzhryc.shared_device.oem.code.statistics.dao.db.ProjectDayStatistics;
import com.gzhryc.shared_device.oem.code.statistics.dao.models.ProjectSumMoneyData;

public class ProjectDayStatisticsService {

    static Logger log = Logger.getLogger(ProjectDayStatisticsService.class);

    public static ProjectDayStatisticsService self() {
        return MultiDBTools.getService(ProjectDayStatisticsService.class, true);
    }

    public static ProjectDayStatisticsService self(String jdbcKey) {
        return MultiDBTools.getService(jdbcKey, ProjectDayStatisticsService.class, true);
    }

    ProjectDayStatisticsDao dao;

    public ProjectDayStatisticsService(String jdbcKey) {
        dao = new ProjectDayStatisticsDao(jdbcKey);
    }

    public List<ProjectDayStatistics> findByDate(Date startDate, Date endDate){
        Conditions conditions = new Conditions(ProjectDayStatistics.class);
        conditions.and().ge("createDate",startDate);
        conditions.and().le("createDate",endDate);

        try {
            return dao.findByCondition(conditions);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public ProjectDayStatistics getOrAddByKeys(Date createDate) {
        if (createDate != null) {
            String dayDate = DateFormatUtils.format(createDate, "yyyyMMdd");
            Conditions conditions = new Conditions(ProjectDayStatistics.class);
            conditions.and().is("dayDate", dayDate);
            try {
                ProjectDayStatistics statistics = dao.get(conditions);
                if (statistics != null) {
                    return statistics;
                }else {
                    Long deviceCount = DeviceService.self().countByDeploy();
                    Long placeCount = PlacePhysicalStoreService.self().countJoinBySearch(new PlacePhysicalStoreSearch());
                    Integer yearNum = Integer.valueOf(DateFormatUtils.format(createDate, "yyyy"));
                    Integer monthNum = Integer.valueOf(DateFormatUtils.format(createDate, "MM"));
                    Integer dayNum = Integer.valueOf(DateFormatUtils.format(createDate, "dd"));
                    statistics = new ProjectDayStatistics();
                    statistics.setDayDate(dayDate);
                    statistics.setYearNum(yearNum);
                    statistics.setMonthNum(monthNum);
                    statistics.setDayNum(dayNum);
                    statistics.setMaxDeviceCount(deviceCount.intValue());
                    statistics.setMaxPlaceCount(placeCount.intValue());
                    statistics.setCreateDate(createDate);

                    if (dao.insert(statistics) > 0) {
                        return statistics;
                    }
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public ProjectSumMoneyData sumAllMoney(){
        ProjectSumMoneyData sumMoneyData = null;
        try {
            sumMoneyData = dao.sumMoneyData(new Conditions());
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        if(sumMoneyData == null){
            sumMoneyData = new ProjectSumMoneyData();
        }
        return sumMoneyData;
    }

    public void addOneOrderData(Date createDate, Long orderMoney,Long orderPayMoney) {
        ProjectDayStatistics statistics = getOrAddByKeys(createDate);
        if (statistics != null) {
            Conditions conditions = new Conditions(ProjectDayStatistics.class);
            conditions.and().is("dayDate", statistics.getDayDate());

            ProjectDayStatistics updateEntity = new ProjectDayStatistics();
            updateEntity.setOrderCount(1);
            updateEntity.setOrderMoney(orderMoney);
            updateEntity.setOrderPayMoney(orderPayMoney);

            try {
                if (dao.updateNotNullAndInc(updateEntity, conditions, "orderCount", "orderMoney", "orderPayMoney") <= 0) {
                    log.error("修改项目统计(支付)失败，时间：{{1}}", createDate);
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        } else {
            log.error("未找到或创建项目统计，时间：{{1}}", createDate);
        }
    }

    public void addOneCancelData(Date refundDate,Long cancelMoney,Date finishDate){
        ProjectDayStatistics statistics = getOrAddByKeys(refundDate);
        if (statistics != null) {
            Conditions conditions = new Conditions(ProjectDayStatistics.class);
            conditions.and().is("dayDate", statistics.getDayDate());
            //同一天则需要修改支付金额
            if (DateTools.isSameDay(refundDate, finishDate)) {
                ProjectDayStatistics updateEntity = new ProjectDayStatistics();
                updateEntity.setCancelOrderCount(1);
                updateEntity.setCancelOrderMoney(cancelMoney);

                try {
                    if (dao.updateNotNullAndInc(updateEntity, conditions, "cancelOrderCount", "cancelOrderMoney") > 0) {
                        updateEntity = new ProjectDayStatistics();
                        updateEntity.setOrderPayMoney(cancelMoney);
                        dao.updateNotNullAndReduce(updateEntity, conditions, "orderPayMoney");
                    } else {
                        log.error("修改项目统计(撤销)失败，时间：{{0}}", refundDate);
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                }
            }else {
                ProjectDayStatistics updateEntity = new ProjectDayStatistics();
                updateEntity.setHistoryCancelOrderCount(1);
                updateEntity.setHistoryCancelOrderMoney(cancelMoney);

                try {
                    if (dao.updateNotNullAndInc(updateEntity, conditions, "historyCancelOrderCount", "historyCancelOrderMoney") <= 0) {
                        log.error("修改项目统计(历史撤销)失败，时间：{{0}}", refundDate);
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                }
            }
        } else {
            log.error("未找到或创建项目统计，撤销统计失败，时间：{{0}}", refundDate);
        }
    }

    public void addOneRefundData(Date refundDate,Long refundMoney,Date finishDate){
        ProjectDayStatistics statistics = getOrAddByKeys(refundDate);
        if (statistics != null) {
            Conditions conditions = new Conditions(ProjectDayStatistics.class);
            conditions.and().is("dayDate", statistics.getDayDate());

            //同一天则需要修改支付金额
            if (DateTools.isSameDay(refundDate, finishDate)) {
                ProjectDayStatistics updateEntity = new ProjectDayStatistics();
                updateEntity.setOrderPayMoney(refundMoney);

                try {
                    if (dao.updateNotNullAndReduce(updateEntity, conditions, "orderPayMoney") <= 0) {
                        log.error("修改项目统计(退款)失败，时间：{{0}}", refundDate);
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                }
            }else{
                ProjectDayStatistics updateEntity = new ProjectDayStatistics();
                updateEntity.setHistoryRefundOrderCount(1);
                updateEntity.setHistoryRefundOrderMoney(refundMoney);

                try {
                    if (dao.updateNotNullAndInc(updateEntity, conditions, "historyRefundOrderCount", "historyRefundOrderMoney") <= 0) {
                        log.error("修改项目统计(历史退款)失败，时间：{{0}}", refundDate);
                    }
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                }
            }
        } else {
            log.error("未找到或创建项目统计，退款统计失败，时间：{{0}}", refundDate);
        }
    }

    public void addOneRechargeData(Date createDate, Integer rechargeMoney) {
        ProjectDayStatistics statistics = getOrAddByKeys(createDate);
        if (statistics != null) {
            Conditions conditions = new Conditions(ProjectDayStatistics.class);
            conditions.and().is("dayDate", statistics.getDayDate());

            ProjectDayStatistics updateEntity = new ProjectDayStatistics();
            updateEntity.setRechargeCount(1);
            updateEntity.setRechargeMoney(rechargeMoney);

            try {
                if (dao.updateNotNullAndInc(updateEntity, conditions, "rechargeCount", "rechargeMoney") <= 0) {
                    log.error("修改项目统计(支付)失败，时间：{{1}}", createDate);
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        } else {
            log.error("未找到或创建项目统计，时间：{{1}}", createDate);
        }
    }

}
